'''
Created on May 7, 2011

@author: james
'''

from Doctors import Doctors
from EvaluatorHelper import EvaluatorHelper

class VacationDaysEvaluator(object):
    '''
    doctor cannot be assigned multiple shifts in same day
    '''

    def __init__(self, schedule, daysOff, noCall, multiplier):
        self._schedule = schedule
        self._daysOff = daysOff
        self._noCall = noCall
        self._multiplier = multiplier
        
    def evaluate(self, chromosome, debug = False):

        totalScore = 0
        score = 0
        maxScore = 0
        
        for day in self._noCall.keys():
            maxScore += len( self._noCall[day] )
            score += len( self._noCall[day] )
            
            index = sum(self._schedule[:day - 1])
                        
            if debug: print "day: %d index: %d, doctor: %d, no call: %s" % (day, index, chromosome[index],  self._noCall[day]) 
            
            if chromosome[index] in self._noCall[day]:
                if debug: print "VacationDaysEvaluator no call penalty, day: %d, doctor: %s" % (day, Doctors().doctorNames[chromosome[index]])  
                score -= 1

        if debug: print "VacationDaysEvaluator no call. Max score %d, Score %d" % (maxScore, score) 
        
        totalScore += score
        maxScore = 0
        score = 0
        
        for day in self._daysOff.keys():
            score += len( self._daysOff[day] )
            maxScore += len( self._daysOff[day] )
            
            beginIndex = sum(self._schedule[:day - 1])
            endIndex = sum(self._schedule[:day])
            
            #[index, remainder] = EvaluatorHelper.getCallShiftIndex(day, self._shiftCycle)
            #index -= 1
            
            #remainder = (day % len(self._shiftCycle))
            #index = (day // len(self._shiftCycle)) * sum(self._shiftCycle) + sum(self._shiftCycle[:remainder]) - 1
            
            for index in range(beginIndex, endIndex):
                if debug: print "day: %d index: %d, doctor: %d, days off: %s" % (day, index, chromosome[index],  self._daysOff[day]) 
                
                if chromosome[index] in self._daysOff[day]:
                    if debug: print "VacationDaysEvaluator day off penalty, day: %d, doctor: %s" % (day, Doctors().doctorNames[chromosome[index]])  
                    score -= 1
                    
        totalScore += score
        
        if debug: print "VacationDaysEvaluator days off max score %d, score: %d" % (maxScore, score)
        if debug: print "VacationDaysEvaluator score: %d" % totalScore
        
        return totalScore * self._multiplier
    
    def evaluateConvergenceCriteria(self, chromosome, attempt):
        
        maxScore = 0
        
        for day in self._daysOff.keys():
            maxScore += len( self._daysOff[day] )
            
        for day in self._noCall.keys():
            maxScore += len( self._noCall[day] )
            
        return self.evaluate(chromosome) == (maxScore * self._multiplier)
        
